

package examples.radio;

import commandz.cli.*;
import commandz.var.Variable;

import java.io.*;
import java.util.Collection;
import java.util.ArrayList;


/**
 *  Example usage of the Interpreter- and Configuration-class.
 *
 *  This application lets a user operate a virtual radio by means of
 *  a command-line interpreter. The configuration of the radio (i.e.
 *  its frequency, volume and modulation-type) can be stored into, and
 *  respectively, loaded from a file.
 */
public final class Example implements Runnable, InterpreterFeedback
{
    public static final String banner =
        "\nInteractive Radio - v1.00\n\n" +
        "End-of-input exits (e.g. ctrl-d or ctrl-z).\n" +
        "Type 'help' for more information.\n\n";

    private static final String prompt = "> ";


    /**
     *  Performs a notification of a argument parse error.
     */
    public void argumentError(final Interpreter source, final Command cmd,
                              final Parameter param, final String argument)
    {
        Variable var = param.getVariable();

        System.out.printf("%s: argument \"%s\" is not a valid value " +
                          "for %s parameter \"%s\".\n", cmd.getName(),
                          argument, var.getTypeName(), param.getName());
    }


    /**
     *  Performs a notification of a argumentation mismatch.
     */
    public void argumentMismatch(final Interpreter source, final Command cmd,
                                 final int expected, final int provided)
    {
        System.out.printf("Syntax: %s", cmd.getName());
    
        Collection<Parameter> params = new ArrayList<Parameter>();
        cmd.publishParameters(params);

        for (Parameter p : params)
        {
            Variable var = p.getVariable();
            System.out.printf(" <%s:%s>", p.getName(), var.getTypeName());
        }
        
        System.out.println();
    }


    /**
     *  Performs a notification of a unknown command error.
     */
    public void unknownCommand(final Interpreter source, final String identifier)
    {
        System.out.printf("%s: unknown command.\n", identifier);
    }


    /**
     *  Runs the example.
     */
    public void run()
    {
        Radio radio = new Radio();

        Interpreter interpreter = new Interpreter(this);
        interpreter.recognize(new HelpCommand(interpreter));
        interpreter.recognize(new TuneCommand(radio));
        interpreter.recognize(new VolumeCommand(radio));
        interpreter.recognize(new AmplitudeModulationCommand(radio));
        interpreter.recognize(new FrequencyModulationCommand(radio));
        interpreter.recognize(new StatusCommand(radio));
        interpreter.recognize(new LoadCommand(radio));
        interpreter.recognize(new StoreCommand(radio));

        Reader source = new InputStreamReader(System.in);
        BufferedReader input = new BufferedReader(source);

        System.out.print(this.banner);

        while (true)  // parse and execute commands..
        {
            String line;

            System.out.print(this.prompt);

            try // to read a line of text..
            {
                line = input.readLine();
            }
            catch (IOException error)
            {
                break;
            }

            if (line == null)  // end of input?
                break;

            interpreter.interpret(line);
        }

        System.out.println("\nEnjoy the silence...");
    }


    /**
     *  Program entry point.
     */
    public static void main(String argv[])
    {
        Runnable example = new Example();
        example.run();
    }

}
